#pragma once
#include <cerrno>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include<iostream>
#include <string>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>

class Sock
{
public:
    Sock(){}
    int Socket()
    {
        int serversock=socket(AF_INET,SOCK_DGRAM,0);
        if(serversock < 0){
            printf("socket() failed:%d:%s",errno,strerror(errno));
            exit(-1);
        }
        return serversock;
    }
    void Bind(int sock,uint16_t port,std::string ip="0.0.0.0")
    {
        struct sockaddr_in server;
        socklen_t len=sizeof(server);
        memset(&server, 0, sizeof(server));
        server.sin_family=AF_INET;
        server.sin_port=htons(port);
        server.sin_addr.s_addr=inet_addr(ip.c_str());
        if(bind(sock, (struct sockaddr*)&server, len) < 0)
        {
            printf("bind() failed:%d:%s",errno,strerror(errno));
            exit(-1);
        }
    }
    void Listen(int sock)
    {
        if(listen(sock, gbacklog) < 0)
        {
            printf("listen() failed:%d:%s",errno,strerror(errno));
            exit(-1);
        }
        printf("listen() is finished\n");
    }
    int Accept(int sock,uint16_t* port,std::string* ip)
    {
        struct sockaddr_in client;
        socklen_t len=sizeof(client);
        //将服务端的这些地址结构接受过来
        int serversock=accept(sock, (struct sockaddr*)&client, &len);
        if(serversock < 0)
        {
            printf("accept() failed:%d:%s",errno,strerror(errno));
            exit(-1);
        }
        if(port){
            *port=ntohs(client.sin_port);
        }
        if(ip){
            *ip=inet_ntoa(client.sin_addr);
        }
        return serversock;
    }
    void Connet(int sock,uint16_t& port,std::string& ip)
    {
        struct sockaddr_in server;
        bzero(&server,sizeof(server));
        socklen_t len=sizeof(server);
        server.sin_family=AF_INET;
        server.sin_port=htons(port);
        server.sin_addr.s_addr=inet_addr(ip.c_str());
        if(connect(sock, (struct sockaddr*)&server, len) < 0)
        {
            printf("connet() failed:%d:%s",errno,strerror(errno));
            exit(-1);
        }
        printf("connet() is finished\n");
    }
private:
    const int gbacklog=20;
};